package it.univaq.di.helpdesk.presentation;

import it.univaq.di.helpdesk.business.common.HelpDeskServiceFactory;
import it.univaq.di.helpdesk.business.common.OfficeService;
import it.univaq.di.helpdesk.business.common.UserService;
import it.univaq.di.helpdesk.business.model.Office;
import it.univaq.di.helpdesk.business.model.Role;
import it.univaq.di.helpdesk.business.model.User;
import it.univaq.di.helpdesk.business.model.UserProfile;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.MappingDispatchAction;

public class ManageUserAction extends MappingDispatchAction {

	public ActionForward activeeditprofile(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		ProfileForm profileForm = (ProfileForm) actionForm;
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		UserService service = factory.getUserService();
		OfficeService officeService = factory.getOfficeService();
		
		//recupero l'ID dell'utente in sessione
		User sessionUser = (User) request.getSession().getAttribute("user");
		User user = service.findUserByID(sessionUser.getUserID());
		
		//copio il contenuto di user dentro profileForm
		BeanUtils.copyProperties(profileForm, user);
		profileForm.setcPassword(user.getPassword());
		
		//Copio il contenuto del profilo dell'utente nel profileForm
		UserProfile profile = user.getProfile();
		if (profile != null) { 
			// Se l'utente non ha un profilo associato la copia non va effettuata
			BeanUtils.copyProperties(profileForm, profile);
		}
		
		//TODO ALERT!!! Permette di selezionare un solo ruolo per l'utente
		Set<Role> roles = user.getRoles();
		String roleName = "";
		for (Role role : roles) {
			roleName = role.getName();
		}
		profileForm.setRoleName(roleName);
		
		profileForm.setOfficeID(user.getOffice().getOfficeID());
		
		List<Role> rolesList = service.findAllRoles();
		request.setAttribute("roles", rolesList);
		
		List<Office> offices = officeService.findAllOffice();
		request.setAttribute("offices", offices);
		
		// Salvataggio del token riutilizzato nel metodo editprofile.
		saveToken(request);
		
		return mapping.findForward("user.activeeditprofile");
	}
	
	/* AJAX Request */
	public ActionForward editprofile(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		/* controlla se il token inserito in sessione dal metodo activeaddticket
		 * è valido rispetto a quello inviato con il submit del form e lo elimina 
		 * dopo l'inserimento 
		 */
		if (!isTokenValid(request, false)) {
			return mapping.findForward("common.doublesubmit");
		}

		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		UserService service = factory.getUserService();
		
		ProfileForm profile = (ProfileForm) actionForm;
		User user = new User();
		BeanUtils.copyProperties(user, profile);
		
		// L'utente non può modificare il suo ruolo!
		/*Set<Role> roleSet = new HashSet<Role>();
		Role role = new Role();
		role.setName(profile.getRoleName());
		roleSet.add(role);
		user.setRoles(roleSet);*/
		
		UserProfile userProfile = new UserProfile();
		BeanUtils.copyProperties(userProfile, profile);
		user.setProfile(userProfile);
		
		Office office = new Office();
		office.setOfficeID(profile.getOfficeID());
		user.setOffice(office);
		
		if (user.getProfile().getUserProfileID() != 0) {
			// Effettuo un update del profilo
			service.editProfile(user);
		} else {
			// Effettuo un insert del profilo
			service.addProfile(user);
		}
				
		// Rimozione del token dalla sessione
		resetToken(request);
		
		return mapping.findForward("common.ok");
	}
	
	// Richiesta AJAX
	public ActionForward viewuserhistory (ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		UserService service = factory.getUserService();
		
		List<Role> rolesList = service.findAllRoles();
		request.setAttribute("role", rolesList);
		
		return mapping.findForward("admin.viewuserhistory");
	}
	
	// Richiesta AJAX
	public ActionForward userlist (ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		UserService service = factory.getUserService();
		
		UserHistoryForm form = (UserHistoryForm) actionForm;
		
		Map<String, String> queryParam = new HashMap<String, String>();
		queryParam.put("firstandlastname", form.getFirstandlastname());
		queryParam.put("role", form.getRole());
		
		List<User> users = service.searchForUsers(queryParam);
		request.setAttribute("users", users);
		
		return mapping.findForward("admin.userlist");
	}
	
	public ActionForward activeadduser (ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		UserService service = factory.getUserService();
		OfficeService serviceOff = factory.getOfficeService();
		
		List<Role> rolesList = service.findAllRoles();
		request.setAttribute("roles", rolesList);
		
		List<Office> officeList = serviceOff.findAllOffice();
		request.setAttribute("offices", officeList);
		
		// Salvataggio del token riutilizzato nel metodo editprofile.
		saveToken(request);
		
		return mapping.findForward("admin.activeadduser");
	}
	
	public ActionForward adduser (ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		/* controlla se il token inserito in sessione dal metodo activeaddticket
		 * è valido rispetto a quello inviato con il submit del form e lo elimina 
		 * dopo l'inserimento 
		 */
		if (!isTokenValid(request, false)) {
			return mapping.findForward("common.doublesubmit");
		}
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		UserService service = factory.getUserService();
		
		User user = new User();
		UserForm userForm = (UserForm) actionForm;
		
		BeanUtils.copyProperties(user, userForm);
		
		Role role = new Role();
		role.setName(userForm.getRoleName());
		Set<Role> roles = new HashSet<Role>();
		roles.add(role);
		user.setRoles(roles);
		
		Office office = new Office();
		office.setOfficeID(userForm.getOfficeID());
		user.setOffice(office);
		
		service.addUser(user);
		
		// Rimozione del token dalla sessione
		resetToken(request);
		
		return mapping.findForward("common.ok");
	}
	
	// AJAX Request
	public ActionForward checkfordupusername(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		String username = request.getParameter("username");
		int userid =  Integer.parseInt(request.getParameter("userid"));
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		UserService service = factory.getUserService();
			
		boolean userPresent = service.isUsernamePresent(username, userid);
		
		response.getWriter().print("{userPresent:" + userPresent + "}");
		
		return null;
	}
	
	public ActionForward activeedituser(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		UserForm userForm = (UserForm) actionForm;
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		UserService service = factory.getUserService();
		OfficeService serviceOff = factory.getOfficeService();
		
		//recupero l'ID dell'utente corrente
		int userID = Integer.parseInt(request.getParameter("userID"));
		User user = service.findUserByID(userID);
		
		//copio il contenuto di user dentro userForm
		BeanUtils.copyProperties(userForm, user);
		userForm.setcPassword(user.getPassword());
		
		Set<Role> roles = user.getRoles();
		String roleName = "";
		for (Role role : roles) {
			roleName = role.getName();
		}
		userForm.setRoleName(roleName);
		Office office = null;
		if((office = user.getOffice()) != null) {
			userForm.setOfficeID(office.getOfficeID());
		}
		
		List<Role> rolesList = service.findAllRoles();
		request.setAttribute("roles", rolesList);
		
		List<Office> officeList = serviceOff.findAllOffice();
		request.setAttribute("offices", officeList);
		
		// Salvataggio del token riutilizzato nel metodo editprofile.
		saveToken(request);
		
		return mapping.findForward("admin.activeedituser");
	}

	/* AJAX Request */
	public ActionForward edituser (ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		/* controlla se il token inserito in sessione dal metodo activeaddticket
		 * è valido rispetto a quello inviato con il submit del form e lo elimina 
		 * dopo l'inserimento 
		 */
		if (!isTokenValid(request, false)) {
			return mapping.findForward("common.doublesubmit");
		}
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		UserService service = factory.getUserService();
		
		User user = new User();
		UserForm userForm = (UserForm) actionForm;
		
		BeanUtils.copyProperties(user, userForm);
		
		Role role = new Role();
		role.setName(userForm.getRoleName());
		Set<Role> roles = new HashSet<Role>();
		roles.add(role);
		user.setRoles(roles);
		
		Office office = new Office();
		office.setOfficeID(userForm.getOfficeID());
		user.setOffice(office);
		
		service.editUser(user);
		
		// Rimozione del token dalla sessione
		resetToken(request);
		
		return mapping.findForward("common.ok");
	}
	
	// AJAX Request
	public ActionForward lockunlockuser (ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		HelpDeskServiceFactory factory = HelpDeskServiceFactory.getInstance();
		UserService service = factory.getUserService();
		
		int userID = Integer.parseInt(request.getParameter("userID"));
		boolean enabled = Boolean.parseBoolean(request.getParameter("enabled"));
		
		User user = new User();
		user.setUserID(userID);
		user.setEnabled(enabled);
		
		service.lockUnlockUser(user);
		
		return null;
	}
}